home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
1122
/
1122.xpi
/
chrome
/
tabmixplus.jar
/
content
/
tabmixplus
/
minit
/
minit.js
< prev
next >
Wrap
Text File
|
2009-09-27
|
36KB
|
940 lines
//code from Dorando and Sboulema's MiniT+, modified by Hemiola SUN
// modified by onemen
const DRAG_LINK = 0;
const DRAG_TAB_TO_NEW_WINDOW = 1;
const DRAG_TAB_IN_SAME_WINDOW = 2;
function TMP_DragAndDrop_init() {
TMP_setDragEvents(true);
if (!gIsFirefox35) {
// for Firefox Dragmark
gBrowser.mTabDropIndicatorBar.addEventListener('dragover', TMP_TabDragOver, true);
gBrowser.mTabDropIndicatorBar.addEventListener('dragdrop', TMP_TabDragDrop, true);
}
// insert vide-bar after update mTabDropIndicatorBar to prevent bug 398254
// Bug 398254 û Since the landing of 372769, I can no longer drag and drop tabs with TabMixPlus
gBrowser.mTabBox.insertBefore(document.getElementById('vide-bar'), gBrowser.mTabBox.firstChild);
var stringBundle = document.getElementById("tmp-string-bundle");
TabDNDObserver.draglink = stringBundle.getString("droplink.label")
}
function TMP_setDragEvents(atStart) {
// we only set Tabmix events at start if Tree Style Tab is not in vertical mode
var useDefaultDnD = false;
if ("TreeStyleTabBrowser" in window) {
try {
var tabbarPosition = gTabmixPrefs.getCharPref("extensions.treestyletab.tabbar.position").toLowerCase();
}
catch (er) {};
useDefaultDnD = tabbarPosition == "left" || tabbarPosition == "right";
}
if (atStart && useDefaultDnD) {
gBrowser.mStrip.useDefaultDnD = useDefaultDnD;
return; // nothing to do here;
}
if ("useDefaultDnD" in gBrowser.mStrip && gBrowser.mStrip.useDefaultDnD == useDefaultDnD) {
return; // nothing to do here;
}
gBrowser.mStrip.useDefaultDnD = useDefaultDnD;
if (useDefaultDnD && gIsFirefox35) {
gBrowser.mStrip.setAttribute("ondragstart", "this.parentNode.parentNode._onDragStart(event);");
gBrowser.mStrip.setAttribute("ondragover", "this.parentNode.parentNode._onDragOver(event);");
gBrowser.mStrip.setAttribute("ondrop", "this.parentNode.parentNode._onDrop(event);");
gBrowser.mStrip.setAttribute("ondragend", "this.parentNode.parentNode._onDragEnd(event);");
gBrowser.mStrip.setAttribute("ondragleave", "this.parentNode.parentNode._onDragLeave(event);");
gBrowser.mTabDropIndicatorBar.setAttribute("ondragover", "this.parentNode.parentNode._onDragOver(event);");
gBrowser.mTabDropIndicatorBar.setAttribute("ondragleave", "this.parentNode.parentNode._onDragLeave(event);");
gBrowser.mTabDropIndicatorBar.setAttribute("ondrop", "this.parentNode.parentNode._onDrop(event);");
}
else if (useDefaultDnD && !gIsFirefox35) {
gBrowser.mStrip.setAttribute("ondraggesture","nsDragAndDrop.startDrag(event, this.parentNode.parentNode); event.stopPropagation();");
gBrowser.mStrip.setAttribute("ondragover","nsDragAndDrop.dragOver(event, this.parentNode.parentNode); event.stopPropagation();");
gBrowser.mStrip.setAttribute("ondragdrop","nsDragAndDrop.drop(event, this.parentNode.parentNode); event.stopPropagation();");
gBrowser.mStrip.setAttribute("ondragexit","nsDragAndDrop.dragExit(event, this.parentNode.parentNode); event.stopPropagation();");
}
else if (gIsFirefox35) {
gBrowser.mStrip.setAttribute("ondragstart", "TabDNDObserver.onDragStart(event)");
gBrowser.mStrip.setAttribute("ondragover", "TabDNDObserver.onDragOver(event)");
gBrowser.mStrip.setAttribute("ondrop", "TabDNDObserver.onDrop(event);");
gBrowser.mStrip.setAttribute("ondragend", "TabDNDObserver.onDragEnd(event);");
gBrowser.mStrip.setAttribute("ondragleave", "TabDNDObserver.onDragExit(event);");
gBrowser.mTabDropIndicatorBar.setAttribute("ondragover", "TabDNDObserver.onDragOver(event);");
gBrowser.mTabDropIndicatorBar.setAttribute("ondragleave", "TabDNDObserver.onDragExit(event);");
gBrowser.mTabDropIndicatorBar.setAttribute("ondrop", "TabDNDObserver.onDrop(event);");
}
else {
gBrowser.mStrip.setAttribute("ondraggesture", "TMP_TabDragGesture(event);");
gBrowser.mStrip.setAttribute("ondragover", "TMP_TabDragOver(event);");
gBrowser.mStrip.setAttribute("ondragdrop", "TMP_TabDragDrop(event);");
gBrowser.mStrip.setAttribute("ondragexit", "TMP_TabDragExit(event);");
}
}
///////////////////////////////////////////////////////////////////////////
//// Drag and Drop observers
function TMP_TabDragGesture(aEvent) {
nsDragAndDrop.startDrag(aEvent, TabDNDObserver);
aEvent.stopPropagation();
}
function TMP_TabDragOver(aEvent) {
nsDragAndDrop.dragOver(aEvent, TabDNDObserver);
aEvent.stopPropagation();
}
function TMP_TabDragDrop(aEvent) {
nsDragAndDrop.drop(aEvent, TabDNDObserver);
aEvent.stopPropagation();
}
function TMP_TabDragExit(aEvent) {
nsDragAndDrop.dragExit(aEvent, TabDNDObserver);
}
var TabDNDObserver = {
gBackupLabel: "",
gMsg: null,
draglink: "",
lastTime: 0,
dragmarkindex: null,
marginBottom: 0,
onDragStart: function (event, transferData, action) {
if (gIsFirefox35)
this._dragLeftWindow = false;
if (event.target.localName != "tab" || event.originalTarget.localName == "toolbarbutton")
return;
for ( var i = 0; i < gBrowser.mTabs.length; i++ )
gBrowser.mTabs[i].setAttribute("showbutton","off");
var draggedTab = event.target;
var uri = gBrowser.getBrowserForTab(draggedTab).currentURI;
var spec = uri ? uri.spec : "about:blank";
if (gIsFirefox35) {
var dt = event.dataTransfer;
dt.mozSetDataAt(TAB_DROP_TYPE, draggedTab, 0);
// We must not set text/x-moz-url or text/plain data here,
// otherwise trying to deatch the tab by dropping it on the desktop
// may result in an "internet shortcut"
dt.mozSetDataAt("text/x-moz-text-internal", spec, 0);
// Set the cursor to an arrow during tab drags.
dt.mozCursor = "default";
var canvas = tabPreviews.capture(draggedTab, false);
dt.setDragImage(canvas, 0, 0);
event.stopPropagation();
}
else { // Firefox 3.0.X
var label = uri ? draggedTab.label : gBrowser.mStringBundle.getString("tabs.untitled");
transferData.data = new TransferData();
transferData.data.addDataForFlavour("text/x-moz-url", spec + "\n" + label);
transferData.data.addDataForFlavour("text/unicode", spec);
transferData.data.addDataForFlavour("text/html", '<a href="' + spec + '">' + label + '</a>');
}
},
onDragOver: function minit_onDragOver(event, flavours, session) {
var dt = event.dataTransfer;
var sourceNode = TMP_getSourceNode(dt, session);
var draggeType = this.getDragType(sourceNode);
var newIndex = this.getNewIndex(event);
var oldIndex = draggeType != DRAG_LINK ? sourceNode._tPos : -1;
var left_right; // 1:right, 0: left, -1: drop link on tab to replace tab
if (newIndex < gBrowser.mTabs.length)
left_right = this.getLeft_Right(event, newIndex, oldIndex, draggeType);
else {
newIndex = draggeType != DRAG_TAB_IN_SAME_WINDOW && tabxPrefs.getBoolPref("openTabNext") ? gBrowser.mTabContainer.selectedIndex :
gBrowser.mTabs.length - 1;
left_right = 1;
}
var isCopy;
if (gIsFirefox35) {
isCopy = dt.dropEffect == "copy";
var effects = this._setEffectAllowedForDataTransfer(event, draggeType);
}
else
isCopy = (event.ctrlKey || event.metaKey);
var replaceTab = (left_right == -1);
/* we don't allow to drop link on lock tab.
* unless:
* - the tab is blank
* or - the user press Ctrl/Meta Key
* or - we drop link that start download
*/
if (replaceTab && !isCopy) {
var targetTab = gBrowser.mTabs[newIndex];
if (targetTab.getAttribute("locked") && !gBrowser.isBlankNotBusyTab(targetTab)) {
try {
var url;
if (gIsFirefox35)
url = this.retrieveURLFromData(dt);
else {
var dropData = nsTransferable.get(new FlavourSet([flavours]), nsDragAndDrop.getDragData, true).first.first;
url = transferUtils.retrieveURLFromData(dropData.data, dropData.flavour.contentType);
}
if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
/^\s*(javascript|data):/.test(url))
url = null;
var disAllowDrop = url ? !isUrlForDownload(url) : true;
} catch (ex) { TMP_ASSERT(ex);}
if (disAllowDrop)
gIsFirefox35 ? dt.effectAllowed = "none" : session.canDrop = false;
}
}
var canDrop;
var hideIndicator = false;
if (gIsFirefox35) {
if (effects == "") {
this.clearDragmark();
return;
}
canDrop = effects != "none";
if (canDrop && !isCopy && draggeType == DRAG_TAB_IN_SAME_WINDOW && oldIndex == newIndex) {
canDrop = false;
dt.effectAllowed = "none";
}
event.preventDefault();
event.stopPropagation();
}
else {
if (draggeType == DRAG_TAB_IN_SAME_WINDOW && oldIndex == newIndex)
session.canDrop = isCopy && event.target != sourceNode;
canDrop = session.canDrop;
if (canDrop && !this.isValidTarget(event, session))
return;
}
// show Drag & Drop message
if (draggeType == DRAG_LINK) {
this.gMsg = event.originalTarget.getAttribute("command") == "cmd_newNavigatorTab" ?
gNavigatorBundle.getString("droponnewtabbutton") : this.draglink;
if (event.target.localName != "tab" && event.target.localName != "tabs")
this.gMsg = this.gBackupLabel;
var statusTextFld = document.getElementById("statusbar-display");
if (statusTextFld.label != this.gMsg) {
if (this.gBackupLabel == "")
this.gBackupLabel = statusTextFld.label;
statusTextFld.label = this.gMsg;
}
}
var tabBar = gBrowser.mTabContainer;
if (tabBar.canScrollTabsLeft || tabBar.canScrollTabsRight) {
var _scroll, targetAnonid;
if (tabscroll > 0) // scroll with button
targetAnonid = event.originalTarget.getAttribute("anonid");
// scroll without button
else if (event.clientX <= tabBar.tabstrip.boxObject.x)
targetAnonid = "scrollbutton-up";
else if(event.clientX >= (tabBar.tabstrip.boxObject.x + tabBar.tabstrip.boxObject.width))
targetAnonid = "scrollbutton-down";
switch (targetAnonid) {
case "scrollbutton-up":
if (tabBar.canScrollTabsLeft)
_scroll = -1;
break;
case "scrollbutton-down":
if (tabBar.canScrollTabsRight)
_scroll = 1;
break;
}
if (_scroll) {
var newTime = new Date().getTime();
if (newTime - this.lastTime > 100) {
gBrowser.mTabContainer.tabsScroll(_scroll);
this.lastTime = newTime;
}
hideIndicator = true;
}
}
// start fix from bug 248612
if (draggeType == DRAG_LINK && event.target.localName == "tab") {
if (!gBrowser.mDragTime)
gBrowser.mDragTime = Date.now();
if (Date.now() >= gBrowser.mDragTime + gBrowser.mDragOverDelay)
gBrowser.mTabContainer.selectedItem = event.target;
}
// end fix from bug 248612
if ( replaceTab || hideIndicator || !canDrop) {
this.clearDragmark();
return;
}
this.setDragmark(newIndex, left_right);
},
onDrop: function minit_onDrop(event, dropData, session) {
this.clearDragmark();
var dt = event.dataTransfer;
var sourceNode = TMP_getSourceNode(dt, session);
var draggeType = this.getDragType(sourceNode);
var isCopy = gIsFirefox35 ? (dt.dropEffect == "copy") : (event.ctrlKey || event.metaKey);
var draggedTab;
if (draggeType != DRAG_LINK) {
draggedTab = sourceNode;
// not our drop then
if (!draggedTab)
return;
}
if (gIsFirefox35) {
event.stopPropagation();
}
var isTabReorder = draggeType == DRAG_TAB_IN_SAME_WINDOW // TreeStyleTab extension look for isTabReorder in our code
var newIndex = this.getNewIndex(event);
var oldIndex = draggedTab ? draggedTab._tPos : -1;
var left_right;
if (newIndex < gBrowser.mTabs.length)
left_right = this.getLeft_Right(event, newIndex, oldIndex, draggeType);
else {
newIndex = draggeType != DRAG_TAB_IN_SAME_WINDOW && tabxPrefs.getBoolPref("openTabNext") ? gBrowser.mTabContainer.selectedIndex :
gBrowser.mTabs.length - 1;
left_right = 1;
}
if (draggedTab && (isCopy || draggeType == DRAG_TAB_IN_SAME_WINDOW)) {
if (isCopy) {
// copy the dropped tab (wherever it's from)
var newTab = gBrowser.duplicateTab(draggedTab);
gBrowser.moveTabTo(newTab, newIndex + left_right);
if (draggeType == DRAG_TAB_TO_NEW_WINDOW || event.shiftKey)
gBrowser.selectedTab = newTab;
}
else {
// move the dropped tab
newIndex += left_right - (newIndex > oldIndex);
if (newIndex != draggedTab._tPos)
gBrowser.moveTabTo(draggedTab, newIndex);
}
draggedTab.collapsed = false;
// probably there is no way to drag collapsed tab....
var firstVisibleIndex = gBrowser.mTabContainer.collapsedTabs;
if ( gBrowser.mTabContainer.getAttribute("flowing") == "multibar" &&
gBrowser.mTabContainer.getAttribute("multibar") == "scrollbar" &&
oldIndex < firstVisibleIndex )
gBrowser.mTabs[firstVisibleIndex - 1].collapsed = true;
gBrowser.mTabContainer.ensureTabIsVisible(newIndex);
checkBeforeAndAfter();
}
else if (draggedTab) {
if (gIsFirefox35) { // Firefox 3.5+
// swap the dropped tab with a new one we create and then close
// it in the other window (making it seem to have moved between
// windows)
newTab = gBrowser.addTab("about:blank");
var newBrowser = gBrowser.getBrowserForTab(newTab);
// Stop the about:blank load
newBrowser.stop();
// make sure it has a docshell
newBrowser.docShell;
gBrowser.moveTabTo(newTab, newIndex + left_right);
gBrowser.swapBrowsersAndCloseOther(newTab, draggedTab);
// We need to set selectedTab after we've done
// swapBrowsersAndCloseOther, so that the updateCurrentBrowser
// it triggers will correctly update our URL bar.
gBrowser.selectedTab = newTab;
}
else {
// Firefox 3.0
// copy the dropped tab and remove it from the other window
// (making it seem to have moved between windows)
var sourceWindow = draggedTab.ownerDocument.defaultView;
var remoteBrowser = sourceWindow.gBrowser;
var tabCount = remoteBrowser.tabContainer.childNodes.length;
newTab = gBrowser.duplicateTab(draggedTab);
gBrowser.moveTabTo(newTab, newIndex + left_right);
gBrowser.selectedTab = newTab;
remoteBrowser.removeTab(draggedTab);
// close the other window if gBrowser was its last tab
if (tabCount == 1)
draggedTab.ownerDocument.defaultView.close();
}
}
else {
var url;
if (gIsFirefox35)
url = this.retrieveURLFromData(dt);
else
url = transferUtils.retrieveURLFromData(dropData.data, dropData.flavour.contentType);
// valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
// Also disallow dropping javascript: or data: urls--bail out
if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
/^\s*(javascript|data):/.test(url))
return;
if (gIsFirefox35) {
var dragService = Cc["@mozilla.org/widget/dragservice;1"].getService(Ci.nsIDragService);
session = dragService.getCurrentSession();
}
nsDragAndDrop.dragDropSecurityCheck(event, session, url);
var bgLoad = true;
try {
bgLoad = gBrowser.mPrefs.getBoolPref("browser.tabs.loadInBackground");
}
catch (e) { }
if (event.shiftKey)
bgLoad = !bgLoad; // shift Key reverse the pref
url = getShortcutOrURI(url);
var tab = null;
if (left_right > -1 && !isUrlForDownload(url)) {
// We're adding a new tab.
try {
tab = gBrowser.addTab(url);
gBrowser.moveTabTo(tab, newIndex + left_right);
} catch(ex) {
// Just ignore invalid urls
tmLog("addTab\n" + ex);
return;
}
}
else {
// Load in an existing tab.
tab = event.target.localName == "tab" ? event.target : gBrowser.mTabs[newIndex];
try {
gBrowser.getBrowserForTab(tab).loadURI(url);
} catch(ex) {
// Just ignore invalid urls
tmLog("load\n" + ex);
return;
}
}
if (gBrowser.mCurrentTab != tab)
gBrowser.TMP_selectNewForegroundTab(tab, bgLoad, url);
}
},
onDragEnd: function minit_onDragEnd(aEvent) {
// see comment in gBrowser._onDragEnd
// don't allow to open new window in single window mode
var dt = aEvent.dataTransfer;
if (gSingleWindowMode || dt.mozUserCancelled || dt.dropEffect != "none")
return;
this.clearDragmark(aEvent);
// Disable detach within the browser toolbox
var eX = aEvent.screenX;
var wX = window.screenX;
// check if the drop point is horizontally within the window
if (eX > wX && eX < (wX + window.outerWidth)) {
// also avoid detaching if the the tab was dropped too close to
// the tabbar (half a tab)
var tabBar = gBrowser.mTabContainer;
var bo = tabBar.mTabstrip.boxObject;
var tabHeight = tabBar.childNodes[tabBar.collapsedTabs].boxObject.height;
var endScreenY = bo.screenY + bo.height + 0.5 * tabHeight;
var eY = aEvent.screenY;
if (gTabbarPosition == 0) {// tabbar on the top
if (eY < endScreenY && eY > window.screenY)
return;
}
else {// bottom
var tb = gNavToolbox.boxObject;
var toolboxEndScreenY = tb.screenY + tb.height;
var startScreenY = bo.screenY - 0.5 * tabHeight;
if ((eY > startScreenY && eY < endScreenY) || eY < toolboxEndScreenY)
return;
}
}
var draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
gBrowser.replaceTabWithWindow(draggedTab);
aEvent.stopPropagation();
},
onDragExit: function minit_onDragExit(event, session) {
event.stopPropagation();
gBrowser.mDragTime = 0;
if (gIsFirefox35) {
var target = event.relatedTarget;
while (target && target.localName != "tabs")
target = target.parentNode;
if (target)
return;
this.clearDragmark();
}
else
this.isValidTarget(event, session);
},
isValidTarget: function minit_isValidTarget(event, session) {
var tabStripBoxObject = gBrowser.mStrip.boxObject;
if ( event.clientY <= tabStripBoxObject.y + 1 ||
event.clientX < tabStripBoxObject.x ||
event.clientY >= tabStripBoxObject.y + tabStripBoxObject.height) {
var statusTextFld = document.getElementById("statusbar-display");
if (statusTextFld.label == this.gMsg) {
statusTextFld.label = this.gBackupLabel;
this.gBackupLabel = "";
}
this.clearDragmark();
gIsFirefox35 ? event.dataTransfer.effectAllowed = "none" : session.canDrop = false;
return false;
}
return true;
},
getNewIndex: function (event) {
// start to chack after collapsedTabs
// if X is less then the first tab return 0
// check if the tab is visible... if not return gBrowser.mTabs.length
// check if Y is below the tab.... if yes go to next row
// in the row find the closest tab by X,
// if no tab is match return gBrowser.mTabs.length
var mX = event.clientX, mY = event.clientY;
var i, tabBar = gBrowser.mTabContainer;
var tabs = tabBar.childNodes;
var collapsed = tabBar.collapsedTabs;
if (!tabBar.hasAttribute("multibar")) {
if (window.getComputedStyle(gBrowser, null).direction == "ltr") {
for (i = event.target.localName == "tab" ? event.target._tPos : collapsed; i < tabs.length; i++)
if (mX < tabs[i].boxObject.x + tabs[i].boxObject.width)
return i;
}
else {
for (i = event.target.localName == "tab" ? event.target._tPos : 0 ; i < tabs.length - collapsed; i++)
if (mX > tabs[i].boxObject.x + tabs[i].boxObject.width*0)
return i;
}
}
else {
var j, tab, thisRow;
var top = tabBar.topTabY;
if (window.getComputedStyle(gBrowser, null).direction == "ltr") {
for (i = collapsed; i < tabs.length; i++) {
if (!tabBar.isTabVisible(i))
return tabs.length;
tab = tabs[i];
thisRow = tabBar.getTabRowNumber(tab, top);
if (mY >= tab.baseY) {
while (i < tabs.length - 1 && tabBar.getTabRowNumber(tabs[i+1], top) == thisRow)
i++;
}
else if (mX < tab.boxObject.x + tab.boxObject.width )
return i;
else if (i == tabs.length - 1 || tabBar.getTabRowNumber(tabs[i+1], top) != thisRow)
return i;
}
}
else {
for (i = collapsed; i < tabs.length; i++) {
if (!tabBar.isTabVisible(i))
return tabs.length;
tab = tabs[i];
thisRow = tabBar.getTabRowNumber(tab, top);
if (mY >= tab.baseY) {
while (i < tabs.length - 1 && tabBar.getTabRowNumber(tabs[i+1], top) == thisRow)
i++;
}
else if (mX > tab.boxObject.x)
return i;
else if (i == tabs.length - 1 || tabBar.getTabRowNumber(tabs[i+1], top) != thisRow)
return i;
}
}
}
return tabs.length;
},
getLeft_Right: function (event, newIndex, oldIndex, draggeType) {
var clientX = event.clientX;
var left_right;
var tab = gBrowser.mTabs[newIndex];
var tabBo = tab.boxObject;
var ltr = (window.getComputedStyle(gBrowser, null).direction == "ltr");
var _left = ltr ? 0 : 1;
var _right = ltr ? 1 : 0;
var isCtrlKey = ((event.ctrlKey || event.metaKey) && !event.shiftKey && !event.altKey);
var lockedTab = tab.getAttribute("locked") && !gBrowser.isBlankNotBusyTab(tab);
if ((draggeType == DRAG_LINK && lockedTab) || (draggeType == DRAG_LINK && !lockedTab && !isCtrlKey)) {
left_right = (clientX < tabBo.x + tabBo.width / 4 ) ? _left : _right;
if (left_right == 1 && clientX < tabBo.x + tabBo.width * 3 / 4 )
left_right = -1;
}
else {
left_right = ( clientX < tabBo.x + tabBo.width / 2 ) ? _left : _right;
if (!isCtrlKey && draggeType == DRAG_TAB_IN_SAME_WINDOW) {
if (newIndex == oldIndex - 1)
left_right = _left;
else if (newIndex == oldIndex + 1)
left_right = _right;
}
}
return left_right;
},
getDragType: function minit_getDragType(aSourceNode) {
if (aSourceNode && aSourceNode instanceof XULElement && aSourceNode.localName == "tab") {
if (aSourceNode.parentNode == gBrowser.mTabContainer)
return DRAG_TAB_IN_SAME_WINDOW; // 2
if (aSourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
aSourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser")
return DRAG_TAB_TO_NEW_WINDOW; // 1
}
return DRAG_LINK; // 0
},
setDragmark: function minit_setDragmark(index, left_right) {
var newIndex = index + left_right;
if (this.dragmarkindex == newIndex)
return;
this.clearDragmark();// clear old dragmark if one exist
if (!tabxPrefs.getBoolPref("useFirefoxDragmark")) {
var sameRow = newIndex != 0 && newIndex != gBrowser.mTabs.length &&
inSameRow(gBrowser.mTabs[newIndex-1], gBrowser.mTabs[newIndex]);
if (sameRow || left_right==0)
this.setDragmarkAttribute(gBrowser.mTabs[newIndex], "atLeft");
if (sameRow || left_right==1)
this.setDragmarkAttribute(gBrowser.mTabs[newIndex-1], "atRight");
}
else {
// code for firefox indicator
var ib = gBrowser.mTabDropIndicatorBar;
var ind = ib.firstChild;
this.setFirefoxDropIndicator(true);
var tabStripBoxObject = gisToolbarMode ? gBrowser.mStrip.boxObject : gBrowser.boxObject;
var scrollBoxObject = gBrowser.mTabContainer.tabstrip.boxObject;
var minMargin = scrollBoxObject.x - tabStripBoxObject.x;
var maxMargin = minMargin + scrollBoxObject.width;
if (!gisToolbarMode)
maxMargin = Math.min(maxMargin, ib.boxObject.x + ib.boxObject.width - ind.boxObject.width);
var ltr = (window.getComputedStyle(gBrowser, null).direction == "ltr");
if (!ltr)
[minMargin, maxMargin] = [tabStripBoxObject.width - maxMargin, tabStripBoxObject.width - minMargin];
if (gTabbarPosition != 1)
this.setFirefoxDropIndicator(false);
var newMargin;
var tabBoxObject = gBrowser.mTabs[index].boxObject;
if (ltr)
newMargin = tabBoxObject.screenX - tabStripBoxObject.screenX + (left_right == 1 ? tabBoxObject.width : 0);
else
newMargin = tabStripBoxObject.screenX - tabBoxObject.screenX + tabStripBoxObject.width - (left_right == 0 ? tabBoxObject.width : 0);
// ensure we never place the drop indicator beyond our limits
if (newMargin < minMargin)
newMargin = minMargin;
else if (newMargin > maxMargin)
newMargin = maxMargin;
var newMarginY;
if (gTabbarPosition == 1) {
newMarginY = tabBoxObject.screenY - (gisToolbarMode ? ind.boxObject.screenY : ib.boxObject.screenY);
}
else {
newMarginY = gBrowser.mTabContainer.boxObject.screenY - tabBoxObject.screenY + this.marginBottom;
}
if (gisToolbarMode) {
newMarginY = (gTabbarPosition == 1 ? 1 : -1) * newMarginY + "px";
ind.style.MozTransform = "translate(" + Math.round(newMargin + ind.boxObject.width / 2) + "px, " + newMarginY + ")";
}
else {
ind.style.MozMarginStart = newMargin + "px";
if (gTabbarPosition == 1)
ind.style.marginTop = newMarginY + "px";
else
ind.style.marginBottom = newMarginY + "px";
}
if (gTabbarPosition == 1) {
ind.style.backgroundPosition = "50% 0%";
}
else {
ind.style.backgroundPosition = "50% 100%";
this.setFirefoxDropIndicator(true);
}
}
this.dragmarkindex = newIndex;
},
clearDragmark: function minit_clearDragmark() {
if (this.dragmarkindex == null)
return;
if (!tabxPrefs.getBoolPref("useFirefoxDragmark")) {
var index = this.dragmarkindex;
if (index != gBrowser.mTabs.length && gBrowser.mTabs[index].hasAttribute("dragmark"))
this.removetDragmarkAttribute(gBrowser.mTabs[index]);
if (index != 0 && gBrowser.mTabs[index-1].hasAttribute("dragmark"))
this.removetDragmarkAttribute(gBrowser.mTabs[index-1]);
}
else
this.setFirefoxDropIndicator(false);
this.dragmarkindex = null;
},
setFirefoxDropIndicator: function (val) {
var indicator = gisToolbarMode ? gBrowser.mTabDropIndicator : gBrowser.mTabDropIndicatorBar;
indicator.collapsed = !val;
},
removetDragmarkAttribute: function (tab) {
tab.removeAttribute("dragmark");
tab.maxWidth = gBrowser.mTabContainer.mTabMaxWidth;
tab.style.maxWidth = tab.maxWidth + "px";
},
setDragmarkAttribute: function (tab, markSide) {
tab.maxWidth = tab.boxObject.width;
tab.style.maxWidth = tab.maxWidth + "px";
tab.setAttribute("dragmark", markSide);
},
/*
* helper function for firefox 3.0.x
*/
getSupportedFlavours: function () {
var flavourSet = new FlavourSet();
flavourSet.appendFlavour("text/x-moz-url");
flavourSet.appendFlavour("text/unicode");
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
return flavourSet;
},
canDrop: function (aEvent, aDragSession) {
if (aDragSession.sourceNode &&
aDragSession.sourceNode.parentNode == gBrowser.mTabContainer) {
var sourceBo = aDragSession.sourceNode.boxObject;
if (aEvent.screenX >= sourceBo.screenX &&
aEvent.screenX <= (sourceBo.screenX +sourceBo.width) &&
aEvent.screenY >= sourceBo.screenY &&
aEvent.screenY <= (sourceBo.screenY +sourceBo.height))
return false;
}
return true;
},
/*
* helper function for firefox 3.5+
*/
_detachTab: function minit__detachTab(aEvent, aTab, aSameWindow) {
// we do here all the work , so always return false
//
// Detach only if the mouse pointer was released a little
// bit down in the content area (to be precise, by tab-height)
var allowDetach = false;
// tabbar on top
if (gTabbarPosition == 0) {
if (aEvent.screenY > gBrowser.mPanelContainer.boxObject.screenY +
aTab.boxObject.height / 2) {
allowDetach = true;
}
}
// tabbar on bottom
else if (aEvent.screenY < gBrowser.mStrip.boxObject.screenY -
aTab.boxObject.height / 2) {
allowDetach = true;
}
if (!allowDetach)
return false;
// The dragend event does not contain information about the pressed modifiers
// XXX check if we can use isCopy = dt.dropEffect == "copy";
var isCopy = (aEvent.ctrlKey || aEvent.metaKey);
if (aSameWindow) { // move or copy to new window
gBrowser.duplicateInWindow(aTab, !isCopy);
}
else { // move or copy to this window
var newTab;
delete aTab.ownerDocument.defaultView.gBrowser._dragLeftWindow;
if (isCopy)
newTab = gBrowser.duplicateTab(aTab);
else {
newTab = gBrowser.addTab("about:blank");
var newBrowser = gBrowser.getBrowserForTab(newTab);
newBrowser.stop();
newBrowser.docShell;
gBrowser.swapBrowsersAndCloseOther(newTab, aTab);
}
gBrowser.selectedTab = newTab;
}
aEvent.dataTransfer.dropEffect = "move";
return false;
},
_setEffectAllowedForDataTransfer: function minit_setEffectAllowed(aEvent, aDraggeType) {
var dt = aEvent.dataTransfer;
// Disallow dropping multiple items
if (dt.mozItemCount > 1)
return dt.effectAllowed = "none";
var sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
// move or copy tab
if (aDraggeType != DRAG_LINK) {
if (aDraggeType == DRAG_TAB_IN_SAME_WINDOW && aEvent.target == sourceNode) {
return dt.effectAllowed = "none";
}
return dt.effectAllowed = "copyMove";
}
var types = dt.mozTypesAt(0);
for (var i = 0; i < gBrowser._supportedLinkDropTypes.length; i++) {
if (types.contains(gBrowser._supportedLinkDropTypes[i])) {
// Here we need to to do this manually
return dt.effectAllowed = dt.dropEffect = "link";
}
}
return dt.effectAllowed = "none";
},
retrieveURLFromData: function minit_retrieveURLFromData(aDataTransfer) {
for (var i=0; i < gBrowser._supportedLinkDropTypes.length; i++) {
var dataType = gBrowser._supportedLinkDropTypes[i];
var isURLList = dataType == "text/uri-list";
var urlData = isURLList ?
aDataTransfer.mozGetDataAt("URL", 0) : aDataTransfer.mozGetDataAt(dataType, 0);
if (urlData)
return transferUtils.retrieveURLFromData(urlData, isURLList ? "text/plain" : dataType);
}
return null;
}
} // TabDNDObserver end
function TMP_goButtonClick(aEvent) {
if (aEvent.button == 1 && gURLBar.value == gBrowser.currentURI.spec)
gBrowser.duplicateTab(gBrowser.mCurrentTab);
else if (aEvent.button != 2) {
if (gIsFirefox35)
gURLBar.handleCommand(aEvent);
else
handleURLBarCommand(aEvent);
}
}
function TM_BrowserHome() {
var homePage = gHomeButton.getHomePage();
if (TMP_whereToOpen(false).inNew) {
var urls = homePage.split("|");
var firstTabAdded = gBrowser.addTab(urls[0]);
var bgLoad = TMP_getBoolPref("browser.tabs.loadBookmarksInBackground", false);
content.focus();
gBrowser.TMP_selectNewForegroundTab(firstTabAdded, bgLoad, urls[0]);
for (var i = 1; i < urls.length; ++i)
gBrowser.addTab(urls[i]);
}
else
loadOneOrMoreURIs(homePage);
}
var undocloseTabButtonObserver = {
onDragOver: function (aEvent, aFlavour, aDragSession) {
var dt = aEvent.dataTransfer;
var sourceNode = TMP_getSourceNode(dt, aDragSession);
if (!sourceNode || sourceNode.localName != "tab") {
gIsFirefox35 ? dt.effectAllowed = "none" : aDragSession.canDrop = false;
return true;
}
var statusTextFld = document.getElementById("statusbar-display");
var stringBundle = document.getElementById("tmp-string-bundle");
statusTextFld.label = stringBundle.getString("droptoclose.label");
aEvent.target.setAttribute("dragover", "true");
return true;
},
onDragExit: function (aEvent, aDragSession) {
if (aEvent.target.hasAttribute("dragover")) {
var statusTextFld = document.getElementById("statusbar-display");
statusTextFld.label = "";
aEvent.target.removeAttribute("dragover");
}
},
onDrop: function (aEvent, aXferData, aDragSession) {
var sourceNode = TMP_getSourceNode(aEvent.dataTransfer, aDragSession);
if (sourceNode && sourceNode.localName == "tab")
// let the tabbrowser drag event time to end before we remove the sourceNode
setTimeout( function (b, aTab) {b.removeTab(aTab, true);}, 0, gBrowser, sourceNode);
},
getSupportedFlavours: function () {
var flavourSet = new FlavourSet();
if (gIsFirefox35)
flavourSet.appendFlavour(TAB_DROP_TYPE);
flavourSet.appendFlavour("text/x-moz-url");
flavourSet.appendFlavour("text/unicode");
return flavourSet;
}
}
/*
* helper function for firefox 3.5+
*/
function TMP_getSourceNode(aDataTransfer, aSession) {
if (gIsFirefox35) {
var types = aDataTransfer.mozTypesAt(0);
if (types[0] == TAB_DROP_TYPE)
return aDataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
return null;
}
return aSession.sourceNode;
}
function TMP_whereToOpen(pref, altKey) {
var aTab = gBrowser.mCurrentTab;
var isBlankTab = gBrowser.isBlankNotBusyTab(aTab);
var isLockTab = !isBlankTab && aTab.hasAttribute("locked");
var openTabPref = typeof(pref) == "string" ? gTabmixPrefs.getBoolPref(pref) : pref;
if (typeof(altKey) != "undefined") {
// don't reuse balnk tab if the user press alt key when the pref is to open in current tab
if (altKey && !openTabPref)
isBlankTab = false;
// see bug 315034 If search is set to open in a new tab,
// Alt+Enter should open the search result in the current tab
// so here we reverse the pref if user press Alt key
openTabPref = (altKey ^ openTabPref) == 1;
}
return { inNew: !isBlankTab && (isLockTab || openTabPref), lock: isLockTab };
}
function TMP_setStripVisibilityTo(aShow) {
if (gisToolbarMode)
gBrowser._toolbar.collapsed = !aShow;
else
gBrowser.mStrip.collapsed = !aShow;
}